home *** CD-ROM | disk | FTP | other *** search
- /*** analog 1.9beta ***/
- /* Please read Readme.html, or http://www.statslab.cam.ac.uk/~sret1/analog/ */
-
- /*** output.c; the output functions, obviously. ***/
-
- #include "analhea2.h"
-
- /* A few variables global to this file */
- int total_succ_reqs, total_fail_reqs, total_other_reqs;
- int total_succ_reqs7, total_fail_reqs7, total_other_reqs7;
-
- /*** The first function prints the "goto" line; links to all reports except
- possibly one (the one we're on). If called gotos('\0') won't omit one.
- If called gotos('z') will omit 'Top'. ***/
-
- void gotos(FILE *outf, char c)
- {
- extern char reportorder[];
- extern flag bq, Bq, cq, dq, Dq, eq, fq, hq, Hq, iq, mq, oq, rq, Sq, Wq, xq;
-
- char *i;
-
- if (xq) {
- fprintf(outf, "\n\n<p>(<b>Go To</b>");
-
- if (c != 'z')
- fprintf(outf, ": <a HREF=\"#Top\">Top</a>");
-
- for (i = reportorder; *i != '\0'; i++) {
- if (c != *i) { /* o/wise we don't want this one */
- switch(*i) {
- case 'b':
- if (bq)
- fprintf(outf, ": <a HREF=\"#Browser\">Browser summary</a>");
- break;
- case 'B':
- if (Bq)
- fprintf(outf, ": <a HREF=\"#FullBrowser\">Browser report</a>");
- break;
- case 'c':
- if (cq)
- fprintf(outf, ": <a HREF=\"#Status\">Status code report</a>");
- break;
- case 'd':
- if (dq)
- fprintf(outf, ": <a HREF=\"#Daily\">Daily summary</a>");
- break;
- case 'D':
- if (Dq)
- fprintf(outf, ": <a HREF=\"#FullDaily\">Daily report</a>");
- break;
- case 'e':
- if (eq)
- fprintf(outf, ": <a HREF=\"#Error\">Error report</a>");
- break;
- case 'f':
- if (fq)
- fprintf(outf, ": <a HREF=\"#Referer\">Referer report</a>");
- break;
- case 'H':
- if (Hq)
- fprintf(outf, ": <a HREF=\"#FullHourly\">Hourly report</a>");
- break;
- case 'h':
- if (hq)
- fprintf(outf, ": <a HREF=\"#Hourly\">Hourly summary</a>");
- break;
- case 'i':
- if (iq)
- fprintf(outf, ": <a HREF=\"#Directory\">Directory report</a>");
- break;
- case 'm':
- if (mq)
- fprintf(outf, ": <a HREF=\"#Monthly\">Monthly report</a>");
- break;
- case 'o':
- if (oq)
- fprintf(outf, ": <a HREF=\"#Domain\">Domain report</a>");
- break;
- case 'r':
- if (rq)
- fprintf(outf, ": <a HREF=\"#Request\">Request report</a>");
- break;
- case 'S':
- if (Sq)
- fprintf(outf, ": <a HREF=\"#Host\">Host report</a>");
- break;
- case 'W':
- if (Wq)
- fprintf(outf, ": <a HREF=\"#Weekly\">Weekly report</a>");
- break;
-
- } /* end switch */
- } /* end if this i wanted */
- } /* end for i */
-
- fprintf(outf, ")\n");
-
- } /* end if xq */
- } /* end function gotos() */
-
- /*** Next, to print strings with HTML reserved characters translated ***/
-
- void htmlputc(char c, FILE *outf)
- {
- if (c == '<')
- fprintf(outf, "<");
- else if (c == '>')
- fprintf(outf, ">");
- else if (c == '&')
- fprintf(outf, "&");
- else if (c == '"')
- fprintf(outf, """);
- else
- putc(c, outf);
- }
-
- void htmlfprintf(FILE *outf, char string[MAXSTRINGLENGTH])
- {
- char *c;
-
- for (c = string; *c != '\0'; c++)
- htmlputc(*c, outf);
-
- }
-
- /*** Now a little routine to find the correct divider for large numbers of
- bytes. Also sets bprefix[0] as a side effect. ***/
-
- double finddivider(double bytes, char *bprefix)
- {
- extern flag rawbytes;
-
- double bdivider;
-
- if (rawbytes)
- bdivider = 1.0;
- else
- for (bdivider = 1; bytes / bdivider >= 999999.5;
- bdivider *= 1024)
- ; /* run bdivider to right multiplier */
-
- if (bdivider == 1.0)
- *bprefix = '\0';
- else if (bdivider == 1024.0)
- *bprefix = 'k';
- else if (bdivider == 1048576.0)
- *bprefix = 'M';
- else if (bdivider == 1073741824.0)
- *bprefix = 'G';
- else if (bdivider == 1099511627776.0)
- *bprefix = 'T';
- else /* 10^6 terabytes should be enough. Just about. */
- *bprefix = '?';
-
- return(bdivider);
- }
-
- /*** print a line across the page, assuming ASCII mode ***/
-
- void asciiline(FILE *outf)
- {
- extern int pagewidth;
-
- int i;
-
- for (i = 0; i < pagewidth; i++)
- fprintf(outf, "-");
- fprintf(outf, "\n\n");
- }
-
- /*** a barchart bar, length n, within <pre><tt> ***/
-
- void barplot(FILE *outf, int n)
- {
- extern int aq;
- extern flag graphical;
- extern char imagedir[];
- extern char markchar;
-
- int i, k;
- flag first = TRUE;
-
- if (aq || !graphical) {
- for ( ; n > 0; n--)
- fprintf(outf, "%c", markchar);
- }
-
- else {
- for (k = 32; k >= 1; k /= 2) {
- while (n >= k) {
- fprintf(outf, "<img src=\"");
- htmlfprintf(outf, imagedir);
- fprintf(outf, "bar%d.gif\" alt=\"", k);
- if (first) {
- for (i = n; i > 0; i--)
- htmlputc(markchar, outf);
- first = FALSE;
- }
- fprintf(outf, "\">");
- n -= k;
- }
- }
- }
- }
-
- /*** A nasty header bit. Return rough floor -- accurate if negative. ***/
-
- int whatincluded(FILE *outf, int sortby, char *minreqstr, char *minbytestr,
- char singular[20], char plural[21], flag subdoms)
- {
- extern double bytefloor(); /* in hash.c */
- extern int reqfloor(); /* in hash.c */
- extern void doublefprintf(); /* in utils.c */
-
- extern double total_bytes;
-
- int genfloor;
- int tempint;
- char tempc;
-
- if (sortby == BYBYTES) {
- if (minbytestr[0] == '-') {
- genfloor = (int)bytefloor(total_bytes, minbytestr);
- if (genfloor == -1)
- fprintf(outf, "Printing the first %s", singular);
- else
- fprintf(outf, "Printing the first %d %s", -genfloor, plural);
- }
- else {
- fprintf(outf, "Printing all %s", plural);
- genfloor = (int)(ceil(bytefloor(total_bytes, minbytestr)));
- if (genfloor > 0) {
- fprintf(outf, " with at least ");
- tempint = MAX((int)strlen(minbytestr) - 1, 0);
- if (minbytestr[tempint] == '%') {
- minbytestr[tempint] = '\0';
- doublefprintf(outf, atof(minbytestr));
- fprintf(outf, "%% of the traffic");
- }
- else if (minbytestr[tempint] == 'k' || minbytestr[tempint] == 'M' ||
- minbytestr[tempint] == 'G' || minbytestr[tempint] == 'T') {
- tempc = minbytestr[tempint];
- minbytestr[tempint] = '\0';
- doublefprintf(outf, atof(minbytestr));
- fprintf(outf, " %cbytes of traffic", tempc);
- }
- else {
- doublefprintf(outf, atof(minbytestr));
- fprintf(outf, " bytes of traffic");
- }
- }
- }
- if (subdoms)
- fprintf(outf, ".\n");
- else
- fprintf(outf, ",%ssorted by amount of traffic.\n",
- (genfloor > 0)?"\n ":" ");
- }
- else { /* sortby not BYBYTES */
- genfloor = reqfloor(total_succ_reqs, minreqstr);
- if (minreqstr[0] == '-') {
- if (genfloor == -1)
- fprintf(outf, "Printing the first %s", singular);
- else
- fprintf(outf, "Printing the first %d %s", -genfloor, plural);
- }
- else {
- fprintf(outf, "Printing all %s", plural);
- if (genfloor > 0) {
- fprintf(outf, " with at least ");
- tempint = MAX((int)strlen(minreqstr) - 1, 0);
- if (minreqstr[tempint] == '%') {
- minreqstr[tempint] = '\0';
- doublefprintf(outf, atof(minreqstr));
- fprintf(outf, "%% of the requests");
- }
- else
- fprintf(outf, "%d request%s", atoi(minreqstr),
- atoi(minreqstr) == 1?"":"s");
- }
- }
- if (subdoms)
- fprintf(outf, ".\n");
- else if (sortby == BYREQUESTS)
- fprintf(outf, ",%ssorted by number of requests.\n",
- (genfloor > 0)?"\n ":" ");
- else if (sortby == ALPHABETICAL)
- fprintf(outf, ",%ssorted alphabetically.\n", (genfloor > 0)?"\n ":" ");
- else
- fprintf(outf, ", unsorted.\n");
- }
-
- return(genfloor);
-
- }
-
-
- /*** Generic output function for generic objects ***/
-
- void genout(FILE *outf, struct genstruct *sorthead, int sortby,
- char *minreqstr, char *minbytestr, int max_reqs, double max_bytes,
- char *wantcols, char anchor[10], char title[17], char singular[13],
- char plural[14], char codeletter, flag alphahost,
- /* alphabetical host sort? */ flag byq, int kq, /* pagelinks? */
- char baseurl[MAXSTRINGLENGTH]) {
-
- extern char *reversehostname(); /* in alias.c */
- extern flag included(); /* in alias.c */
-
- extern int pagewidth;
- extern int dirlevel;
- extern int host_max_length;
- extern int aq;
- extern flag rawbytes;
- extern double total_bytes;
- extern struct include *ispagehead;
-
- struct genstruct *p;
- int fieldwidth, bfieldwidth, graphwidth;
- int genfloor;
- double bdivider;
- char bprefix[2];
- char *cols;
- double pc;
- int pc1, pc2;
- int i, j, tempint;
- char *tempc;
-
- bprefix[0] = '\0';
- bprefix[1] = '\0';
-
- if (!aq) {
- fprintf(outf,
- "\n\n<hr>\n<h2><a NAME=\"%s\">%s</a></h2>\n\n", anchor, title);
- gotos(outf, codeletter);
- fprintf(outf, "<p>");
- }
- else {
- fprintf(outf, "%s\n", title);
- for (tempc = title; *tempc != '\0'; tempc++)
- fprintf(outf, "-");
- fprintf(outf, "\n");
- }
-
- genfloor = whatincluded(outf, sortby, minreqstr, minbytestr, singular,
- plural, FALSE);
- if (codeletter == 'i') {
- if (!aq)
- fprintf(outf, "<br>");
- fprintf(outf, "Printing directories to depth %d.\n", dirlevel);
- }
-
- if (aq)
- fprintf(outf, "\n");
- else
- fprintf(outf, "<pre>");
-
-
- tempint = 10000;
- for (fieldwidth = 5; max_reqs / tempint >= 10; fieldwidth++)
- tempint *= 10;
-
- if (byq) {
- if (rawbytes) {
- tempint = 100000;
- for (bfieldwidth = 6; max_bytes / tempint >= 10; bfieldwidth++)
- tempint *= 10;
- }
- else
- bfieldwidth = 6;
-
- bdivider = finddivider(max_bytes, bprefix);
- }
-
- for (cols = wantcols; *cols != '\0'; cols++) {
- switch(*cols) {
- case 'R':
- for (i = 5; i < fieldwidth; i++)
- fprintf(outf, " ");
- fprintf(outf, "#reqs: ");
- break;
- case 'r':
- fprintf(outf, " %%reqs: ");
- break;
- case 'B':
- if (byq) {
- for (i = 6; i < bfieldwidth; i++)
- fprintf(outf, " ");
- fprintf(outf, "%sbytes: ", bprefix[0] == '\0'?" ":bprefix);
- }
- break;
- case 'b':
- if (byq)
- fprintf(outf, "%%bytes: ");
- break;
- }
- }
- fprintf(outf, "%s\n", singular);
-
- for (cols = wantcols; *cols != '\0'; cols++) {
- switch(*cols) {
- case 'R':
- for (i = 1; i <= fieldwidth; i++)
- fprintf(outf, "-");
- fprintf(outf, " ");
- break;
- case 'r':
- fprintf(outf, "------ ");
- break;
- case 'B':
- if (byq) {
- for (i = 1; i <= bfieldwidth; i++)
- fprintf(outf, "-");
- fprintf(outf, " ");
- }
- break;
- case 'b':
- if (byq)
- fprintf(outf, "------ ");
- break;
- }
- }
- for (tempc = singular; *tempc != '\0'; tempc++)
- fprintf(outf, "-");
- fprintf(outf, "\n");
-
- if (genfloor < 0)
- j = genfloor;
- else j = 1;
-
- if (alphahost) {
- graphwidth = pagewidth;
- for (cols = wantcols; *cols != '\0'; cols++) {
- switch(*cols) {
- case 'R':
- graphwidth -= fieldwidth + 2;
- break;
- case 'B':
- graphwidth -= bfieldwidth + 2;
- break;
- case 'r':
- case 'b':
- graphwidth -= 8;
- break;
- }
- }
- graphwidth = MIN(graphwidth, host_max_length);
- }
-
- for(p = sorthead; p -> name != NULL && (j++) != 0;
- p = p -> next) {
-
- for (cols = wantcols; *cols != '\0'; cols++) {
- switch(*cols) {
- case 'R':
- fprintf(outf, "%*d: ", fieldwidth, p -> reqs);
- break;
- case 'r':
- pc = (p -> reqs + 0.0) / ((total_succ_reqs + 0.0) / 10000);
- pc1 = ((int)(pc + 0.5)) / 100; /* whole no. of %reqs */
- pc2 = ((int)(pc + 0.5)) % 100; /* remaining 100ths. */
- if (pc1 == 100)
- fprintf(outf, " 100%%: ");
- else if (pc1 > 0 || pc2 > 0)
- fprintf(outf, "%2d.%02d%%: ", pc1, pc2);
- else
- fprintf(outf, " : ");
- break;
- case 'B':
- if (byq) {
- if (p -> bytes / bdivider > 0.5)
- fprintf(outf, "%*.0lf", bfieldwidth, p -> bytes / bdivider);
- else for (i = 0; i < bfieldwidth; i++)
- fprintf(outf, " ");
- fprintf(outf, ": ");
- }
- break;
- case 'b':
- if (byq) {
- pc = p -> bytes / (total_bytes / 10000);
- pc1 = ((int)(pc + 0.5)) / 100; /* whole no. of %bytes */
- pc2 = ((int)(pc + 0.5)) % 100; /* remaining 100ths. */
- if (pc1 == 100)
- fprintf(outf, " 100%%: ");
- else if (pc1 > 0 || pc2 > 0)
- fprintf(outf, "%2d.%02d%%: ", pc1, pc2);
- else
- fprintf(outf, " : ");
- }
- break;
- }
- }
-
- if (alphahost && !isdigit(p -> name[0])) { /* we've swapped the names */
- reversehostname(p -> name);
- /* Also in that case right align names */
- for (i = graphwidth - (int)strlen(p -> name); i > 0; i--)
- fprintf(outf, " ");
- }
-
- if ((kq == 2) ||
- /* if we want to link to everything ... */
- (kq == 1 && included(p -> name, ispagehead))) {
- /* or it is a page, and we want to link to pages */
- fprintf(outf, "<a HREF=\"");
- htmlfprintf(outf, baseurl);
- htmlfprintf(outf, p -> name);
- fprintf(outf, "\">");
- htmlfprintf(outf, p -> name);
- fprintf(outf, "</a>");
- }
- else /* (the usual case for most reports) */
- if (!aq)
- htmlfprintf(outf, p -> name);
- else
- fprintf(outf, p -> name);
- fprintf(outf, "\n");
-
- }
-
- if (aq)
- asciiline(outf);
- else
- fprintf(outf, "</pre>");
-
- }
-
- /*** The domain report is similar to the generic ones. It differs in that
- the domains are stored in a different structure, and that subdomains
- must be printed. ***/
-
- void domout(FILE *outf, int firstdom)
- {
- extern struct domain *domainhead[];
- extern int aq;
- extern flag byq, rawbytes;
- extern int domsortby;
- extern char domminbytestr[], domminreqstr[];
- extern char subdomminbytestr[], subdomminreqstr[];
- extern int dom_max_reqs;
- extern double dom_max_bytes;
- extern int subonumber;
- extern char domcols[];
- extern double total_bytes;
-
- int domfloor;
-
- struct domain *domp;
- double bdivider;
- char bprefix[2];
- char *cols;
- int fieldwidth, bfieldwidth;
- double pc;
- int pc1, pc2;
- int i, j, k, tempint;
- char *tempp;
-
- bprefix[0] = '\0';
- bprefix[1] = '\0';
-
- if (!aq) {
- fprintf(outf,
- "\n\n<hr>\n<h2><a NAME=\"Domain\">Domain Report</a></h2>\n\n");
- gotos(outf, 'o');
- }
- else {
- fprintf(outf, "Domain Report\n");
- fprintf(outf, "-------------\n");
- }
-
- if (!aq)
- fprintf(outf, "<p>");
-
- domfloor = whatincluded(outf, domsortby, domminreqstr, domminbytestr,
- "domain", "domains", FALSE);
- if (subonumber > 0) {
- if (!aq)
- fprintf(outf, "<br>");
- whatincluded(outf, domsortby, subdomminreqstr, subdomminbytestr,
- "requested subdomain", "requested subdomains", TRUE);
- }
-
- if (aq)
- fprintf(outf, "\n");
- else
- fprintf(outf, "<pre>");
-
- tempint = 10000;
- for (fieldwidth = 5; dom_max_reqs / tempint >= 10; fieldwidth++)
- tempint *= 10;
-
- if (byq) {
- if (rawbytes) {
- tempint = 100000;
- for (bfieldwidth = 6; dom_max_bytes / tempint >= 10; bfieldwidth++)
- tempint *= 10;
- }
- else
- bfieldwidth = 6;
-
- bdivider = finddivider(dom_max_bytes, bprefix);
- }
-
- for (cols = domcols; *cols != '\0'; cols++) {
- switch(*cols) {
- case 'R':
- for (i = 5; i < fieldwidth; i++)
- fprintf(outf, " ");
- if (subonumber > 0)
- fprintf(outf, " #reqs : ");
- else
- fprintf(outf, "#reqs: ");
- break;
- case 'r':
- if (subonumber > 0)
- fprintf(outf, " %%reqs : ");
- else
- fprintf(outf, " %%reqs: ");
- break;
- case 'B':
- if (byq) {
- for (i = 6; i < bfieldwidth; i++)
- fprintf(outf, " ");
- if (subonumber > 0)
- fprintf(outf, " %sbytes : ", bprefix[0] == '\0'?" ":bprefix);
- else
- fprintf(outf, "%sbytes: ", bprefix[0] == '\0'?" ":bprefix);
- }
- break;
- case 'b':
- if (byq) {
- if (subonumber > 0)
- fprintf(outf, " %%bytes : ");
- else
- fprintf(outf, "%%bytes: ");
- }
- break;
- }
- }
- fprintf(outf, "domain\n");
-
- for (cols = domcols; *cols != '\0'; cols++) {
- switch(*cols) {
- case 'R':
- for (i = 1; i <= fieldwidth; i++)
- fprintf(outf, "-");
- if (subonumber > 0)
- fprintf(outf, "--");
- fprintf(outf, " ");
- break;
- case 'r':
- if (subonumber > 0)
- fprintf(outf, "--");
- fprintf(outf, "------ ");
- break;
- case 'B':
- if (byq) {
- for (i = 1; i <= bfieldwidth; i++)
- fprintf(outf, "-");
- if (subonumber > 0)
- fprintf(outf, "--");
- fprintf(outf, " ");
- }
- break;
- case 'b':
- if (byq) {
- if (subonumber > 0)
- fprintf(outf, "--");
- fprintf(outf, "------ ");
- }
- break;
- }
- }
- fprintf(outf, "------\n");
-
- if (domfloor < 0)
- j = domfloor;
- else j = 1;
-
- for (i = firstdom; i >= 0 && (j++) != 0; i = domainhead[i] -> nexti) {
-
- if (!(i == DOMHASHSIZE - 2 && domainhead[i] -> reqs == -1)) {
-
- for (cols = domcols; *cols != '\0'; cols++) {
- switch(*cols) {
- case 'R':
- if (subonumber > 0)
- fprintf(outf, " %*d : ", fieldwidth,
- domainhead[i] -> reqs);
- else
- fprintf(outf, "%*d: ", fieldwidth, domainhead[i] -> reqs);
- break;
- case 'r':
- pc = (domainhead[i] -> reqs + 0.0) /
- ((total_succ_reqs + 0.0) / 10000);
- pc1 = ((int)(pc + 0.5)) / 100; /* whole no. of %reqs */
- pc2 = ((int)(pc + 0.5)) % 100; /* remaining 100ths. */
- if (subonumber > 0)
- fprintf(outf, " ");
- if (pc1 == 100)
- fprintf(outf, " 100%%");
- else if (pc1 > 0 || pc2 > 0)
- fprintf(outf, "%2d.%02d%%", pc1, pc2);
- else
- fprintf(outf, " ");
- if (subonumber > 0)
- fprintf(outf, " : ");
- else
- fprintf(outf, ": ");
- break;
- case 'B':
- if (byq) {
- if (domainhead[i] -> bytes / bdivider > 0.5) {
- if (subonumber > 0)
- fprintf(outf, " %*.0lf ", bfieldwidth,
- domainhead[i] -> bytes / bdivider);
- else
- fprintf(outf, "%*.0lf", bfieldwidth,
- domainhead[i] -> bytes / bdivider);
- }
- else for (k = 0; k < bfieldwidth + 2 * (subonumber > 0); k++)
- fprintf(outf, " ");
- fprintf(outf, ": ");
- }
- break;
- case 'b':
- if (byq) {
- pc = domainhead[i] -> bytes / (total_bytes / 10000);
- pc1 = ((int)(pc + 0.5)) / 100; /* whole no. of %bytes */
- pc2 = ((int)(pc + 0.5)) % 100; /* remaining 100ths. */
- if (subonumber > 0)
- fprintf(outf, " ");
- if (pc1 == 100)
- fprintf(outf, " 100%%");
- else if (pc1 > 0 || pc2 > 0)
- fprintf(outf, "%2d.%02d%%", pc1, pc2);
- else
- fprintf(outf, " ");
- if (subonumber > 0)
- fprintf(outf, " : ");
- else
- fprintf(outf, ": ");
- }
- break;
- }
- }
-
- if (domainhead[i] -> id[0] == '*')
- /* flagged domains, not real domain names */
- fprintf(outf, "[%s]\n", domainhead[i] -> name);
- else if (domainhead[i] -> name[0] == '?')
- /* real domain, but don't print name */
- fprintf(outf, ".%s\n", domainhead[i] -> id);
- else
- fprintf(outf, ".%s (%s)\n", domainhead[i] -> id,
- domainhead[i] -> name);
-
- /* Now print its subdomains too. */
-
- for (domp = domainhead[i] -> next; domp -> name != NULL;
- domp = domp -> next) {
-
- for (cols = domcols; *cols != '\0'; cols++) {
- switch(*cols) {
- case 'R':
- fprintf(outf, "(%*d): ", fieldwidth, domp -> reqs);
- break;
- case 'r':
- pc = (domp -> reqs + 0.0) /
- ((total_succ_reqs + 0.0) / 10000);
- pc1 = ((int)(pc + 0.5)) / 100; /* whole no. of %reqs */
- pc2 = ((int)(pc + 0.5)) % 100; /* remaining 100ths. */
- if (pc1 == 100)
- fprintf(outf, "( 100%%): ");
- else if (pc1 > 0 || pc2 > 0)
- fprintf(outf, "(%2d.%02d%%): ", pc1, pc2);
- else
- fprintf(outf, " : ");
- break;
- case 'B':
- if (byq) {
- if (domp -> bytes / bdivider > 0.5)
- fprintf(outf, "(%*.0lf)", bfieldwidth,
- domp -> bytes / bdivider);
- else for (k = 0; k < bfieldwidth + 2; k++)
- fprintf(outf, " ");
- fprintf(outf, ": ");
- }
- break;
- case 'b':
- if (byq) {
- pc = domp -> bytes / (total_bytes / 10000);
- pc1 = ((int)(pc + 0.5)) / 100; /* whole no. of %bytes */
- pc2 = ((int)(pc + 0.5)) % 100; /* remaining 100ths. */
- if (pc1 == 100)
- fprintf(outf, "( 100%%): ");
- else if (pc1 > 0 || pc2 > 0)
- fprintf(outf, "(%2d.%02d%%): ", pc1, pc2);
- else
- fprintf(outf, " : ");
- }
- break;
- }
- }
-
- tempp = domp -> id;
- while ((tempp = strchr(tempp, '.')) != NULL) {
- fprintf(outf, " ");
- /* print two spaces for each dot in name */
- tempp++;
- }
- if (i == DOMHASHSIZE - 1)
- fprintf(outf, " "); /* + 2 more for numerical domains */
- fprintf(outf, "%s", domp -> id);
-
- if (domp -> name[0] != '?') /* print name */
- fprintf(outf, " (%s)", domp -> name);
-
- fprintf(outf, "\n");
-
- } /* end for domp */
-
- }
-
- } /* end for (i = running over domains) */
-
- if (aq)
- asciiline(outf);
- else
- fprintf(outf, "</pre>");
-
- }
-
- /*** The date reports aren't quite generic enough to combine completely,
- but we can go a long way towards it. ***/
- /*** First a function for printing out the headers of a report and finding
- the fieldwidths etc.; then one for printing out each individual line. ***/
-
- void datehead(FILE *outf, int maxreq, double maxbytes,
- char *wantcols, char *graphtype, char anchor[11],
- char title[15], char colhead[13], char codeletter,
- int *unit, int *fieldwidth, int *bfieldwidth, int *graphwidth,
- double *bdivider) /* NB: colhead: inc. leading spaces. */
- /* The last 5 args are returned altered */
- {
- extern void int3printf(); /* in utils.c */
-
- extern int aq;
- extern flag byq, rawbytes;
- extern int pagewidth;
- extern char imagedir[];
- extern char markchar;
-
- char *cols;
- char bprefix[2];
- int i, j, tempint;
- char *tempc;
-
- bprefix[0] = '\0';
- bprefix[1] = '\0';
-
- if (*graphtype == 'b')
- *graphtype = 'B';
-
- if (!aq) {
- fprintf(outf, "<hr>\n<h2><a NAME=\"%s\">%s</a></h2>\n", anchor, title);
- gotos(outf, codeletter);
- }
- else {
- fprintf(outf, "%s\n", title);
- for (tempc = title; *tempc != '\0'; tempc++)
- fprintf(outf, "-");
- fprintf(outf, "\n");
- }
-
- tempint = 10000;
- for (*fieldwidth = 5; maxreq / tempint >= 10; (*fieldwidth)++)
- tempint *= 10; /* so fieldwidth is log_10(maxreq), but >= 5 */
-
- if (byq) {
- if (rawbytes || (*graphtype == 'B' && *unit > 0)) {
- tempint = 100000;
- for (*bfieldwidth = 6; maxbytes / tempint >= 10; (*bfieldwidth)++)
- tempint *= 10;
- }
- else
- *bfieldwidth = 6;
-
- *bdivider = finddivider(maxbytes, bprefix);
- }
-
- if (*unit <= 0) { /* (o/wise just use the given amount) */
-
- /* Calculate the graphwidth */
- *graphwidth = pagewidth - (int)strlen(colhead) - 2;
- for (cols = wantcols; *cols != '\0'; cols++) {
- switch(*cols) {
- case 'R':
- *graphwidth -= *fieldwidth + 2;
- break;
- case 'B':
- *graphwidth -= *bfieldwidth + 2;
- break;
- case 'r':
- case 'b':
- *graphwidth -= 8;
- break;
- }
- }
- *graphwidth = MAX(*graphwidth, MINGRAPHWIDTH); /* must be >= MGW wide */
-
- if (*graphtype == 'B')
- *unit = (maxbytes - 1) / (*bdivider * *graphwidth);
- else
- *unit = (maxreq - 1) / *graphwidth;
- /* except we want a 'nice' amount, so ... */
- /* (Nice amount is 1, 1.5, 2, 2.5, 3, 4, 5, 6, 8 * 10^n */
-
- j = 0;
- while (*unit > 24) {
- *unit /= 10;
- j++;
- }
- if (*unit == 6)
- *unit = 7;
- else if (*unit == 8)
- *unit = 9;
- else if (*unit >= 20)
- *unit = 24;
- else if (*unit >= 15)
- *unit = 19;
- else if (*unit >= 10)
- *unit = 14;
- (*unit)++;
- for (i = 0; i < j; i++) {
- *unit *= 10;
- }
-
- } /* end if (*unit <= 0) */
-
- else if (*graphtype == 'B') { /* o/wise unit doesn't make sense */
- *bdivider = 1;
- bprefix[0] = '\0';
- }
-
- if (!aq) {
- fprintf(outf, "\n<p>Each unit (<tt><img src=\"");
- htmlfprintf(outf, imagedir);
- fprintf(outf, "bar1.gif\" alt=\"");
- htmlputc(markchar, outf);
- fprintf(outf, "\"></tt>) represents ");
- int3printf(outf, *unit);
- if (*graphtype == 'B')
- fprintf(outf, " %sbyte%s, or part thereof.", bprefix,
- (*unit == 1)?"":"s");
- else
- fprintf(outf, " request%s.", (*unit == 1)?"":"s, or part thereof");
- fprintf(outf, "\n\n<pre width=%d><tt>\n", pagewidth);
- }
- else {
- fprintf(outf, "\nEach unit (%c) represents ", markchar);
- int3printf(outf, *unit);
- if (*graphtype == 'B')
- fprintf(outf, " %sbyte%s, or part thereof.\n\n", bprefix,
- (*unit == 1)?"":"s");
- else
- fprintf(outf, " request%s.\n\n",
- (*unit == 1)?"":"s, or part thereof");
- }
-
- fprintf(outf, "%s: ", colhead);
- for (cols = wantcols; *cols != '\0'; cols++) {
- switch(*cols) {
- case 'R':
- for (i = 5; i < *fieldwidth; i++)
- fprintf(outf, " ");
- fprintf(outf, "#reqs: ");
- break;
- case 'r':
- fprintf(outf, " %%reqs: ");
- break;
- case 'B':
- if (byq) {
- for (i = 6; i < *bfieldwidth; i++)
- fprintf(outf, " ");
- fprintf(outf, "%sbytes: ", bprefix[0] == '\0'?" ":bprefix);
- }
- break;
- case 'b':
- if (byq)
- fprintf(outf, "%%bytes: ");
- break;
- }
- }
-
- fprintf(outf, "\n");
- for (tempc = colhead; *tempc != '\0'; tempc++)
- fprintf(outf, "-");
- fprintf(outf, " ");
- for (cols = wantcols; *cols != '\0'; cols++) {
- switch(*cols) {
- case 'R':
- for (i = 1; i <= *fieldwidth; i++)
- fprintf(outf, "-");
- fprintf(outf, " ");
- break;
- case 'r':
- fprintf(outf, "------ ");
- break;
- case 'B':
- if (byq) {
- for (i = 1; i <= *bfieldwidth; i++)
- fprintf(outf, "-");
- fprintf(outf, " ");
- }
- break;
- case 'b':
- if (byq)
- fprintf(outf, "------ ");
- break;
- }
- }
- fprintf(outf, "\n");
- }
-
- /* As promised, each separate line. We print name of date in output() though */
-
- void dateline(FILE *outf, int reqs, double bytes, char *wantcols,
- char graphtype, int fieldwidth, int bfieldwidth,
- int unit, int bdivider) {
- extern double total_bytes;
- extern flag byq;
-
- char *cols;
- double pc;
- int pc1, pc2;
-
- for (cols = wantcols; *cols != '\0'; cols++) {
- switch(*cols) {
- case 'R':
- fprintf(outf, "%*d: ", fieldwidth, reqs);
- break;
- case 'r':
- pc = (reqs + 0.0) / ((total_succ_reqs + 0.0) / 10000);
- pc1 = ((int)(pc + 0.5)) / 100; /* whole no. of %reqs */
- pc2 = ((int)(pc + 0.5)) % 100; /* remaining 100ths. */
- if (pc1 == 100)
- fprintf(outf, " 100%%: ");
- else if (pc1 > 0 || pc2 > 0)
- fprintf(outf, "%2d.%02d%%: ", pc1, pc2);
- else
- fprintf(outf, " : ");
- break;
- case 'B':
- if (byq)
- fprintf(outf, "%*.0lf: ", bfieldwidth, bytes / bdivider);
- break;
- case 'b':
- if (byq) {
- pc = bytes / (total_bytes / 10000);
- pc1 = ((int)(pc + 0.5)) / 100; /* whole no. of %bytes */
- pc2 = ((int)(pc + 0.5)) % 100; /* remaining 100ths. */
- if (pc1 == 100)
- fprintf(outf, " 100%%: ");
- else if (pc1 > 0 || pc2 > 0)
- fprintf(outf, "%2d.%02d%%: ", pc1, pc2);
- else
- fprintf(outf, " : ");
- }
- break;
- }
- }
- if (graphtype == 'B')
- barplot(outf, (int)(ceil(bytes / (unit * bdivider))));
- else
- barplot(outf, (reqs == 0)?0:((reqs - 1) / unit) + 1);
- fprintf(outf, "\n");
- }
-
- /*** The status code report (very simple) ***/
-
- void statusout(FILE *outf)
- {
- extern int status[], statusnos[];
- extern char statusstrs[NO_STATUS][MAXSTATUSLENGTH];
- extern int aq;
-
- int fieldwidth;
- int maxreqs = 0;
- int i;
-
- for (i = 0; i < NO_STATUS; i++)
- maxreqs = MAX(maxreqs, status[i]);
-
- if (!aq) {
- fprintf(outf, "\n\n<hr>\n<h2><a NAME=\"Status\">Status Code Report</a></h2>\n\n");
- gotos(outf, 'c');
- fprintf(outf, "<pre>");
- }
- else
- fprintf(outf, "Status Code Report\n------------------\n\n");
-
- i = 10000;
- for (fieldwidth = 5; maxreqs / i >= 10; fieldwidth++)
- i *= 10;
-
- for (i = 5; i < fieldwidth; i++)
- fprintf(outf, " ");
- fprintf(outf, "#occs: no. description\n");
- for (i = 0; i < fieldwidth; i++)
- fprintf(outf, "-");
- fprintf(outf, " ---------------\n");
-
- for (i = 0; i < NO_STATUS; i++) {
- if (status[i] > 0) {
- if (statusstrs[i][0] == '0')
- fprintf(outf, "%*d: %s\n", fieldwidth, status[i], statusstrs[i]);
- else
- fprintf(outf, "%*d: %d %s\n", fieldwidth, status[i], statusnos[i],
- statusstrs[i]);
- }
- }
-
- if (aq)
- asciiline(outf);
- else
- fprintf(outf, "</pre>");
- }
-
- /*** Finally in the individual report printing, the error report ***/
-
- void errout(FILE *outf, int errorder[NO_ERRS])
- {
- extern int errors[NO_ERRS];
- extern char errs[NO_ERRS][MAXERRLENGTH];
- extern int errminreqs;
- extern int aq;
-
- int fieldwidth;
- int i;
-
- if (errors[errorder[0]] >= errminreqs) { /* o/wise no report */
-
- if (!aq) {
- fprintf(outf,
- "\n\n<hr>\n<h2><a NAME=\"Error\">Error Report</a></h2>\n\n");
- gotos(outf, 'e');
- fprintf(outf, "<p>");
- }
- else
- fprintf(outf, "Error Report\n------------\n");
-
- if (errminreqs == 0)
- fprintf(outf, "Printing all possible errors, ");
- else
- fprintf(outf, "Printing all errors with at least %d occurence%s,\n",
- errminreqs, (errminreqs == 1)?"":"s");
- fprintf(outf, " sorted by number of occurrences.");
-
- if (aq)
- fprintf(outf, "\n\n");
- else
- fprintf(outf, "<pre>");
-
- i = 10000;
- for (fieldwidth = 5; errors[errorder[0]] / i >= 10; fieldwidth++)
- i *= 10;
-
- for (i = 5; i < fieldwidth; i++)
- fprintf(outf, " ");
- fprintf(outf, "#occs: error type\n");
- for (i = 0; i < fieldwidth; i++)
- fprintf(outf, "-");
- fprintf(outf, " ----------\n");
-
- for (i = 0; errors[errorder[i]] >= errminreqs && i < NO_ERRS; i++)
- fprintf(outf, "%*d: %s\n", fieldwidth, errors[errorder[i]],
- (errs[errorder[i]][0] == '\0')?"[unknown]":errs[errorder[i]]);
-
- if (aq)
- asciiline(outf);
- else
- fprintf(outf, "</pre>");
- }
- }
-
-
- /*** Now the main output function which calls all that stuff ***/
-
- void output(struct genstruct *urlsorthead, struct genstruct *dirsorthead,
- struct genstruct *hostsorthead, int firstdom,
- struct genstruct *refsorthead, struct genstruct *browsorthead,
- struct genstruct *fullbrowsorthead, int errorder[])
- {
- extern int dayofdate(); /* in utils.c */
- extern int minsbetween(); /* in utils.c */
- extern void int3printf(); /* in utils.c */
- extern void double3printf(); /* in utils.c */
-
- extern char outfile[];
- extern char dayname[7][4];
- extern char monthname[12][4];
- extern int monthlength[];
- extern char hostname[];
- extern char logourl[];
- extern char hosturl[];
- extern char commandname[];
- extern char headerfile[];
- extern char footerfile[];
- extern char reportorder[];
- extern flag q7, byq, refbyq, browbyq, kq, warnq;
- extern flag mback, Dback, Wback, Hback;
- extern flag xq, dq, Dq, Wq, hq, Hq, mq, Sq, rq, oq, iq, fq, bq, Bq, cq, eq;
- extern int sq, aq;
- extern char starttimestr[];
- extern struct timestruct firsttime, lasttime, oldtime, totime, starttimec;
- extern time_t starttime, stoptime;
- extern int weekbeginson;
- extern struct monthly *firstm, *lastm;
- extern struct weekly *firstw, *lastw;
- extern struct daily *firstd, *lastd;
- extern struct hourly *firsth, *lasth;
- extern int dailyreq[], hourlyreq[];
- extern double dailybytes[], hourlybytes[];
- extern int monthlyunit, weeklyunit, hourlyunit, fullhourlyunit, dailyunit;
- extern int fulldailyunit;
- extern int cachereqs, cachereqs7, corrupt_lines, other_lines;
- extern int no_urls, no_hosts, no_urls7, no_hosts7, no_new_hosts7;
- extern double total_bytes, total_bytes7;
- extern int pagewidth;
- extern int hostsortby, reqsortby, dirsortby;
- extern int refsortby, browsortby, fullbrowsortby;
- extern char hostminreqstr[], urlminreqstr[], dirminreqstr[], refminreqstr[];
- extern char browminreqstr[], fullbrowminreqstr[];
- extern char hostminbytestr[], urlminbytestr[], dirminbytestr[];
- extern char refminbytestr[], browminbytestr[], fullbrowminbytestr[];
- extern char monthgraph, daygraph, fulldaygraph, hourgraph, fullhourgraph;
- extern char weekgraph;
- extern char monthcols[], daycols[], fulldaycols[], hourcols[], weekcols[];
- extern char fullhourcols[], reqcols[], dircols[], hostcols[], refcols[];
- extern char browcols[], fullbrowcols[];
- extern char imagedir[], baseurl[];
- extern int reqtype;
- extern int status[], status7[], statusnos[];
- extern int dir_max_reqs, host_max_reqs, url_max_reqs,
- ref_max_reqs, brow_max_reqs, fullbrow_max_reqs;
- extern double dir_max_bytes, host_max_bytes, url_max_bytes;
-
- FILE *outf; /* the output file */
- int totalmins; /* between first and last entries analysed */
- int fieldwidth; /* Width we require to print #reqs in */
- int bfieldwidth; /* #bytes ditto */
- char bprefix[2]; /* kilo, Mega, etc. */
- int graphwidth; /* the width left for a graph after columns written */
- struct monthly *mp;
- struct daily *dp;
- struct weekly *wp;
- struct hourly *hp;
- int maxreq; /* within a particular date report */
- double maxbytes;
- double bdivider;
- int year, monthno, date;
- flag finished;
- int i, j, firsti, lasti;
- char *ro;
- char tempstr[MAXSTRINGLENGTH];
- FILE *tempf;
-
- bprefix[0] = '\0';
- bprefix[1] = '\0';
-
- total_succ_reqs = cachereqs;
- total_fail_reqs = 0;
- total_other_reqs = 0;
- total_succ_reqs7 = cachereqs7;
- total_fail_reqs7 = 0;
- total_other_reqs7 = 0;
- for (i = 0; i < NO_STATUS; i++) {
- if (statusnos[i] <= 299 || statusnos[i] == 304) {
- total_succ_reqs += status[i];
- total_succ_reqs7 += status7[i];
- }
- else if (statusnos[i] <= 399) {
- total_other_reqs += status[i];
- total_other_reqs7 += status7[i];
- }
- else {
- total_fail_reqs += status[i];
- total_fail_reqs7 += status7[i];
- }
- }
-
- if (STREQ(outfile, "stdout"))
- outf = stdout;
-
- else if ((outf = fopen(outfile, "w")) == NULL) {
- fprintf(stderr, "%s: Error: failed to open output file %s for writing.\n",
- commandname, outfile);
- exit(ERR); /* shouldn't get here because also tested at the beginning */
- } /* (unless it's vanished in the meantime or something) */
-
- if (aq == CACHE)
- fprintf(outf,
- "CACHE type 1 produced by analog%s. Do not modify or delete!",
- VERSION);
- else {
- if (!aq) {
- fprintf(outf, "<html>\n<head><title>Web Server Statistics for ");
- htmlfprintf(outf, hostname);
- fprintf(outf, "</title></head>\n");
- fprintf(outf, "<body>\n<h1><a NAME=\"Top\">");
- if (!STREQ(logourl, "none")) {
- fprintf(outf, "<IMG src=\"");
- htmlfprintf(outf, logourl);
- fprintf(outf, "\" alt=\"\"> ");
- }
- if (hosturl[0] == '-') {
- fprintf(outf, "Web Server Statistics</a> for ");
- htmlfprintf(outf, hostname);
- }
- else {
- fprintf(outf, "Web Server Statistics</a> for <a HREF=\"");
- htmlfprintf(outf, hosturl);
- fprintf(outf, "\">");
- htmlfprintf(outf, hostname);
- fprintf(outf, "</a>");
- }
- fprintf(outf, "</h1>\n\n");
- }
- else {
- fprintf(outf, "Web Server Statistics for %s\n", hostname);
- fprintf(outf, "==========================");
- for (i = (int)strlen(hostname); i > 0; i--)
- fprintf(outf, "=");
- fprintf(outf, "\n");
- }
-
- /* insert header file */
-
- headerfile[MAXSTRINGLENGTH - 5] = '\0'; /* for safety */
-
- if (!STREQ(headerfile, "none")) {
- if ((tempf = fopen(headerfile, "r")) == NULL) {
- if (warnq)
- fprintf(stderr,
- "%s: Warning: Failed to open headerfile %s: ignoring it.\n",
- commandname, headerfile);
- }
- else { /* can open header file */
- if (!aq)
- fprintf(outf, "<hr>");
- else
- fprintf(outf, "\n");
-
- while(fgets(tempstr, MAXLINELENGTH, tempf) != NULL)
- fprintf(outf, "%s", tempstr);
- fclose(tempf);
- if (tempstr[(int)strlen(tempstr) - 1] != '\n')
- fprintf(outf, "\n");
-
- if (aq) {
- for (i = 0; i < pagewidth; i++)
- fprintf(outf, "-");
- }
-
- fprintf(outf, "\n");
-
- }
- }
- }
-
- /* Summary statistics */
-
- if (xq) {
-
- if (!aq)
- fprintf(outf, "<hr>");
-
- fprintf(outf,
- "\nProgram started at %c%c%c-%c%c-%c%c%c-%c%c%c%c %c%c:%c%c local time.\n",
- starttimestr[0], starttimestr[1], starttimestr[2],
- (starttimestr[8]==' ')?'0':starttimestr[8], starttimestr[9],
- starttimestr[4], starttimestr[5], starttimestr[6],
- starttimestr[20], starttimestr[21], starttimestr[22],
- starttimestr[23],
- starttimestr[11], starttimestr[12],
- starttimestr[14], starttimestr[15]);
-
- if (firsttime.code > oldtime.code)
- q7 = OFF;
-
- if (total_succ_reqs > 0) {
- totalmins = minsbetween(firsttime.date, firsttime.monthno, firsttime.year,
- firsttime.hr, firsttime.min,
- lasttime.date, lasttime.monthno, lasttime.year,
- lasttime.hr, lasttime.min) + 1;
- if (!aq)
- fprintf(outf, "<br>");
- fprintf(outf,
- "Analysed requests from %s-%02d-%s-%d %02d:%02d to %s-%02d-%s-%d %02d:%02d\n (%.1f days).\n\n",
- dayname[dayofdate(firsttime.date,
- firsttime.monthno, firsttime.year)],
- firsttime.date, monthname[firsttime.monthno], firsttime.year,
- firsttime.hr, firsttime.min,
- dayname[dayofdate(lasttime.date, lasttime.monthno,
- lasttime.year)],
- lasttime.date, monthname[lasttime.monthno], lasttime.year,
- lasttime.hr, lasttime.min,
- (double)totalmins / 1440.0);
- }
-
- if (!aq)
- fprintf(outf, "<p><b>Total completed requests:</b> ");
- else
- fprintf(outf, "Total completed requests: ");
- int3printf(outf, total_succ_reqs);
- if (q7) {
- fprintf(outf, " (");
- int3printf(outf, total_succ_reqs7);
- fprintf(outf, ")");
- }
- if (totalmins > 30) {
- if (!aq)
- fprintf(outf, "\n<br><b>Average completed requests per day:</b> ");
- else
- fprintf(outf, "\nAverage completed requests per day: ");
- if (total_succ_reqs < 2)
- fprintf(outf, "0");
- else
- double3printf(outf, ((double)(total_succ_reqs - 1)) * 1440.0 / (totalmins + 0.0));
- if (q7) {
- fprintf(outf, " (");
- int3printf(outf, total_succ_reqs7 / 7);
- fprintf(outf, ")");
- }
- }
- if (total_fail_reqs > 0) {
- if (!aq)
- fprintf(outf, "\n<br><b>Total failed requests:</b> ");
- else
- fprintf(outf, "\nTotal failed requests: ");
- int3printf(outf, total_fail_reqs);
- if (q7) {
- fprintf(outf, " (");
- int3printf(outf, total_fail_reqs7);
- fprintf(outf, ")");
- }
- }
- if (total_other_reqs > 0) {
- if (!aq)
- fprintf(outf, "\n<br><b>Total redirected requests:</b> ");
- else
- fprintf(outf, "\nTotal redirected requests: ");
- int3printf(outf, total_other_reqs);
- if (q7) {
- fprintf(outf, " (");
- int3printf(outf, total_other_reqs7);
- fprintf(outf, ")");
- }
- }
- if (rq) { /* These data are not collected o/wise (rq => this > 0) */
- if (!aq)
- fprintf(outf, "\n<br><b>Number of distinct files requested:</b> ");
- else
- fprintf(outf, "\nNumber of distinct files requested: ");
- int3printf(outf, no_urls);
- if (q7) {
- fprintf(outf, " (");
- int3printf(outf, no_urls7);
- fprintf(outf, ")");
- }
- }
- if ((sq == ON || sq == APPROX) && no_hosts > 0) {
- if (!aq)
- fprintf(outf, "\n<br><b>%sumber of distinct hosts served:</b> ",
- (sq == ON)?"N":"Approximate n");
- else
- fprintf(outf, "\n%sumber of distinct hosts served: ",
- (sq == ON)?"N":"Approximate n");
- int3printf(outf, no_hosts);
- if (q7) {
- fprintf(outf, " (");
- int3printf(outf, no_hosts7);
- fprintf(outf, ")");
- if (!aq)
- fprintf(outf,
- "\n<br><b>%sumber of new hosts served in last 7 days:</b> ",
- (sq == ON)?"N":"Approximate n");
- else
- fprintf(outf, "\n%sumber of new hosts served in last 7 days: ",
- (sq == ON)?"N":"Approximate n");
- int3printf(outf, no_new_hosts7);
- }
- }
- if (corrupt_lines > 0) {
- if (!aq)
- fprintf(outf, "\n<br><b>Corrupt logfile lines:</b> ");
- else
- fprintf(outf, "\nCorrupt logfile lines: ");
- int3printf(outf, corrupt_lines);
- }
- if (other_lines > 0) {
- if (!aq)
- fprintf(outf, "\n<br><b>Unwanted logfile entries:</b> ");
- else
- fprintf(outf, "\nUnwanted logfile entries: ");
- int3printf(outf, other_lines);
- }
- if (byq) {
- if (!aq)
- fprintf(outf, "\n<br><b>Total data transferred:</b> ");
- else
- fprintf(outf, "\nTotal data transferred: ");
- bdivider = finddivider(total_bytes, bprefix);
- double3printf(outf, ROUND(total_bytes / bdivider));
- fprintf(outf, " %sbytes", bprefix);
- if (q7) {
- fprintf(outf, " (");
- bdivider = finddivider(total_bytes7, bprefix);
- double3printf(outf, ROUND(total_bytes7 / bdivider));
- fprintf(outf, " %sbytes)", bprefix);
- }
- if (totalmins > 30) {
- if (!aq)
- fprintf(outf, "\n<br><b>Average data transferred per day:</b> ");
- else
- fprintf(outf, "\nAverage data transferred per day: ");
- bdivider = finddivider((total_bytes * 1440) / (totalmins + 0.0),
- bprefix);
- double3printf(outf,
- ROUND((total_bytes * 1440) / (totalmins + 0.0) / bdivider));
- fprintf(outf, " %sbytes", bprefix);
- if (q7) {
- fprintf(outf, " (");
- bdivider = finddivider(total_bytes7 / 7.0, bprefix);
- double3printf(outf, ROUND(total_bytes7 / 7.0 / bdivider));
- fprintf(outf, " %sbytes)", bprefix);
- }
- }
- }
- if (q7) {
- if (!aq)
- fprintf(outf, "\n<br>");
- else
- fprintf(outf, "\n");
- fprintf(outf, "(Figures in parentheses refer to the ");
- if (starttimec.code > totime.code)
- fprintf(outf, "7 days to %02d-%s-%4d).", totime.date,
- monthname[totime.monthno], totime.year);
- else
- fprintf(outf, "last 7 days).");
- }
-
- if (!aq && (mq || Wq || dq || Dq || hq || oq || Sq || iq || rq))
- gotos(outf, 'z');
- if (aq) {
- fprintf(outf, "\n");
- asciiline(outf);
- }
-
- } /* end if xq */
-
- else if (aq == ASCII)
- printf("\n");
-
- /* Now for the rest of the reports, in reportorder order */
-
- for (ro = reportorder; *ro != '\0'; ro++) {
-
- switch(*ro) {
-
- case 'm': /* Monthly report */
-
- if (mq) {
-
- maxreq = 0;
- maxbytes = 0.0;
- finished = FALSE;
- for (mp = mback?lastm:firstm; !finished; mp = mp -> next) {
- for (i = 0; i < 12; i++) {
- maxreq = MAX(maxreq, mp -> reqs[i]);
- maxbytes = MAX(maxbytes, mp -> bytes[i]);
- }
- if (mp == (mback?firstm:lastm))
- finished = TRUE;
- }
-
- datehead(outf, maxreq, maxbytes, monthcols, &monthgraph,
- "Monthly", "Monthly Report", " month", 'm', &monthlyunit,
- &fieldwidth, &bfieldwidth, &graphwidth, &bdivider);
-
- finished = FALSE;
- year = (mback?lasttime:firsttime).year;
- for (mp = mback?lastm:firstm; !finished; mp = mp -> next) {
- if (mp == firstm) {
- firsti = firsttime.monthno;
- if (mback)
- finished = TRUE;
- }
- else
- firsti = 0;
- if (mp == lastm) {
- lasti = lasttime.monthno;
- if (!mback)
- finished = TRUE;
- }
- else
- lasti = 11;
- for (i = mback?lasti:firsti; mback?(i >= firsti):(i <= lasti);
- i += mback?(-1):1) { /* run through months in chosen order */
- fprintf(outf, "%s %d: ", monthname[i], year);
- dateline(outf, mp -> reqs[i], mp -> bytes[i], monthcols,
- monthgraph, fieldwidth, bfieldwidth, monthlyunit,
- bdivider);
- }
- year += mback?(-1):1;
- }
-
- if (aq)
- asciiline(outf);
- else
- fprintf(outf, "</tt></pre>");
-
- }
-
- break;
-
- case 'W': /* Weekly report */
-
- if (Wq) {
-
- maxreq = 0;
- maxbytes = 0.0;
- finished = FALSE;
- for (wp = Wback?lastw:firstw; !finished; wp = wp -> next) {
- maxreq = MAX(maxreq, wp -> reqs);
- maxbytes = MAX(maxbytes, wp -> bytes);
- if (wp == (Wback?firstw:lastw))
- finished = TRUE;
- }
-
- datehead(outf, maxreq, maxbytes, weekcols, &weekgraph,
- "Weekly", "Weekly Report", "week beg.", 'W', &weeklyunit,
- &fieldwidth, &bfieldwidth, &graphwidth, &bdivider);
-
- finished = FALSE;
- for (wp = Wback?lastw:firstw; !finished; wp = wp -> next) {
- fprintf(outf, "%2d/%s/%02d: ", wp -> start.date,
- monthname[wp -> start.monthno], wp -> start.year % 100);
- dateline(outf, wp -> reqs, wp -> bytes, weekcols, weekgraph,
- fieldwidth, bfieldwidth, weeklyunit, bdivider);
- if (wp == (Wback?firstw:lastw))
- finished = TRUE;
-
- } /* end running through weeks */
-
- if (aq)
- asciiline(outf);
- else
- fprintf(outf, "</tt></pre>");
-
- } /* end if Wq */
-
- break;
-
- case 'd': /* Daily summary */
-
- if (dq) {
-
- maxreq = 0;
- maxbytes = 0.0;
- for (i = 0; i <= 6; i++) {
- maxreq = MAX(maxreq, dailyreq[i]);
- maxbytes = MAX(maxbytes, dailybytes[i]);
- }
-
- datehead(outf, maxreq, maxbytes, daycols, &daygraph,
- "Daily", "Daily Summary", "day", 'd', &dailyunit,
- &fieldwidth, &bfieldwidth, &graphwidth, &bdivider);
-
- for(i = 0; i <= 6; i++) {
- j = (weekbeginson + i) % 7;
- fprintf(outf, "%s: ", dayname[j]);
- dateline(outf, dailyreq[j], dailybytes[j], daycols, daygraph,
- fieldwidth, bfieldwidth, dailyunit, bdivider);
- }
-
- if (aq)
- asciiline(outf);
- else
- fprintf(outf, "</tt></pre>");
-
- }
-
- break;
-
- case 'D': /* Full daily report */
-
- if (Dq) {
-
- maxreq = 0;
- maxbytes = 0.0;
- finished = FALSE;
- for (dp = Dback?lastd:firstd; !finished; dp = dp -> next) {
- for (i = 0; i < 31; i++) {
- maxreq = MAX(maxreq, dp -> reqs[i]);
- maxbytes = MAX(maxbytes, dp -> bytes[i]);
- }
- if (dp == (Dback?firstd:lastd))
- finished = TRUE;
- }
-
- datehead(outf, maxreq, maxbytes, fulldaycols, &fulldaygraph,
- "FullDaily", "Daily Report", " date", 'D',
- &fulldailyunit, &fieldwidth, &bfieldwidth, &graphwidth,
- &bdivider);
-
- finished = FALSE;
- year = (Dback?lasttime:firsttime).year;
- monthno = (Dback?lasttime:firsttime).monthno;
- for (dp = Dback?lastd:firstd; !finished; dp = dp -> next) {
- if (dp == firstd) {
- firsti = firsttime.date - 1;
- if (Dback)
- finished = TRUE;
- }
- else
- firsti = 0;
- if (dp == lastd) {
- lasti = lasttime.date - 1;
- if (!Dback)
- finished = TRUE;
- }
- else
- lasti = monthlength[monthno] + ISLEAPFEB(monthno, year) - 1;
- for (i = Dback?lasti:firsti; Dback?(i >= firsti):(i <= lasti);
- i += Dback?(-1):1) { /* run through days in chosen order */
- fprintf(outf, "%2d/%s/%02d: ", i + 1, monthname[monthno],
- year % 100);
- dateline(outf, dp -> reqs[i], dp -> bytes[i], fulldaycols,
- fulldaygraph, fieldwidth, bfieldwidth, fulldailyunit,
- bdivider);
- if (((dayofdate(i + 1, monthno, year) + (!Dback)) % 7 ==
- weekbeginson) && !(finished && i == (Dback?firsti:lasti)))
- fprintf(outf, "\n");
- /* extra blank line after each week (not last) */
- }
-
- if (Dback) {
- if ((--monthno) == -1) {
- monthno = 11;
- --year;
- }
- }
- else {
- if ((++monthno) == 12) {
- monthno = 0;
- ++year;
- }
- }
-
- } /* end running through dp's */
-
- if (aq)
- asciiline(outf);
- else
- fprintf(outf, "</tt></pre>");
-
- } /* end if Dq */
-
- break;
-
- case 'H': /* Full hourly report */
-
- if (Hq) {
-
- maxreq = 0;
- maxbytes = 0.0;
- finished = FALSE;
- for (hp = Hback?lasth:firsth; !finished; hp = hp -> next) {
- for (i = 0; i < 24; i++) {
- maxreq = MAX(maxreq, hp -> reqs[i]);
- maxbytes = MAX(maxbytes, hp -> bytes[i]);
- }
- if (hp == (Hback?firsth:lasth))
- finished = TRUE;
- }
-
- if (aq != CACHE)
- datehead(outf, maxreq, maxbytes, fullhourcols, &fullhourgraph,
- "FullHourly", "Hourly Report", " date:hr", 'H',
- &fullhourlyunit, &fieldwidth, &bfieldwidth, &graphwidth,
- &bdivider);
-
- finished = FALSE;
- year = (Hback?lasttime:firsttime).year;
- monthno = (Hback?lasttime:firsttime).monthno;
- date = (Hback?lasttime:firsttime).date;
- for (hp = Hback?lasth:firsth; !finished; hp = hp -> next) {
- if (hp == firsth) {
- firsti = firsttime.hr;
- if (Hback)
- finished = TRUE;
- }
- else
- firsti = 0;
- if (hp == lasth) {
- lasti = lasttime.hr;
- if (!Hback)
- finished = TRUE;
- }
- else
- lasti = 23;
- for (i = Hback?lasti:firsti; Hback?(i >= firsti):(i <= lasti);
- i += Hback?(-1):1) { /* run through hours in chosen order */
- if (aq == CACHE) {
- if (i == 0 || (hp == firsth && i == firsti))
- fprintf(outf, "\n%d%02d%02d%02d", year, monthno + 1, date, i);
- fprintf(outf, ":%d:%.0lf", hp -> reqs[i], hp -> bytes[i]);
- }
- else {
- fprintf(outf, "%2d/%s/%02d:%02d: ", date, monthname[monthno],
- year % 100, i);
- dateline(outf, hp -> reqs[i], hp -> bytes[i], fullhourcols,
- fullhourgraph, fieldwidth, bfieldwidth, fullhourlyunit,
- bdivider);
- if (i == (Hback?0:23) && !finished)
- fprintf(outf, "\n");
- /* extra blank line after each day (not last) */
- }
- }
-
- if (Hback) {
- if ((--date) == 0) {
- if ((--monthno) == -1) {
- monthno = 11;
- --year;
- }
- date = monthlength[monthno] + ISLEAPFEB(monthno, year);
- }
- }
- else {
- if ((++date) > monthlength[monthno] + ISLEAPFEB(monthno, year)) {
- if ((++monthno) == 12) {
- monthno = 0;
- ++year;
- }
- date = 1;
- }
- }
-
- } /* end running through hp's */
-
- if (aq == CACHE)
- fprintf(outf, ":*\n");
- else if (aq)
- asciiline(outf);
- else if (!aq)
- fprintf(outf, "</tt></pre>");
-
- } /* end if Hq */
-
- break;
-
- case 'h': /* Hourly summary */
-
- if (hq) {
-
- maxreq = 0;
- maxbytes = 0.0;
- for (i = 0; i <= 23; i++) {
- maxreq = MAX(maxreq, hourlyreq[i]);
- maxbytes = MAX(maxbytes, hourlybytes[i]);
- }
-
- datehead(outf, maxreq, maxbytes, hourcols, &hourgraph, "Hourly",
- "Hourly Summary", "hr", 'h', &hourlyunit, &fieldwidth,
- &bfieldwidth, &graphwidth, &bdivider);
-
- for(i = 0; i <= 23; i++) {
- fprintf(outf, "%2d: ", i);
- dateline(outf, hourlyreq[i], hourlybytes[i], hourcols, hourgraph,
- fieldwidth, bfieldwidth, hourlyunit, bdivider);
- }
-
- if (aq)
- asciiline(outf);
- else
- fprintf(outf, "</tt></pre>");
-
- }
-
- break;
-
- case 'o': /* Domain report */
-
- if (oq)
- domout(outf, firstdom);
-
- break;
-
- case 'S': /* Host report */
-
- if (Sq)
- genout(outf, hostsorthead, hostsortby, hostminreqstr, hostminbytestr,
- host_max_reqs, host_max_bytes, hostcols,
- "Host", "Host Report", "host", "hosts", 'S',
- hostsortby == ALPHABETICAL, byq, OFF, "");
- break;
-
- case 'i': /* Directory report */
-
- if (iq)
- genout(outf, dirsorthead, dirsortby, dirminreqstr, dirminbytestr,
- dir_max_reqs, dir_max_bytes, dircols, "Directory",
- "Directory Report", "directory", "directories", 'i', FALSE,
- byq, OFF, "");
- break;
-
- case 'r': /* Request report */
-
- if (rq) {
- if (aq)
- kq = 0; /* no links in ASCII output! */
- else if (reqtype == PAGES)
- kq = 2; /* If only printing pages, any linked = all linked */
- genout(outf, urlsorthead, reqsortby, urlminreqstr, urlminbytestr,
- url_max_reqs, url_max_bytes, reqcols, "Request",
- "Request Report", (reqtype == PAGES)?"page":"file",
- (reqtype == PAGES)?"pages":"files", 'r', FALSE, byq, kq,
- baseurl);
- }
- break;
-
- case 'f': /* Referer report */
-
- if (fq)
- genout(outf, refsorthead, refsortby, refminreqstr, refminbytestr,
- ref_max_reqs, 0, refcols, "Referer", "Referer Report",
- "refering URL", "refering URLs", 'f', FALSE, refbyq, !aq, "");
- break;
-
- case 'b': /* Browser summary */
-
- if (bq)
- genout(outf, browsorthead, browsortby, browminreqstr, browminbytestr,
- brow_max_reqs, 0, browcols, "Browser", "Browser Summary",
- "browser", "browsers", 'b', FALSE, browbyq, OFF, "");
- break;
-
- case 'B': /* Full browser report */
-
- if (Bq)
- genout(outf, fullbrowsorthead, fullbrowsortby, fullbrowminreqstr,
- fullbrowminbytestr, fullbrow_max_reqs, 0, fullbrowcols,
- "FullBrowser", "Browser Report", "browser", "browsers", 'B',
- FALSE, browbyq, OFF, "");
- break;
-
- case 'c':
-
- if (cq)
- statusout(outf);
- break;
-
- case 'e':
-
- if (eq)
- errout(outf, errorder);
- break;
-
- } /* end switch */
- } /* end for ro */
-
-
- /*** Bit at the bottom of the page ***/
-
- if (aq != CACHE) {
- if (!aq)
- fprintf(outf, "\n\n<hr>\n<i>This analysis was produced by <a HREF=\"http://www.statslab.cam.ac.uk/~sret1/analog/\">analog%s</a>.\n", VERSION);
- else
- fprintf(outf, "This analysis was produced by analog%s.\n", VERSION);
-
- time(&stoptime);
-
- stoptime -= starttime; /* so now measures elapsed time */
-
- if (stoptime == 0) {
- if (!aq)
- fprintf(outf, "<br><b>Running time:</b> Less than 1 second.</i>\n");
- else
- fprintf(outf, "Running time: Less than 1 second.\n");
- }
-
- else if (stoptime < 60) {
- if (!aq)
- fprintf(outf, "<br><b>Running time:</b> %ld second%s.</i>\n",
- stoptime, (stoptime == 1)?"":"s");
- else
- fprintf(outf, "Running time: %ld second%s.\n",
- stoptime, (stoptime == 1)?"":"s");
- }
-
- else {
- if (!aq)
- fprintf(outf,
- "<br><b>Running time:</b> %ld minute%s, %ld second%s.</i>\n",
- stoptime / 60, (stoptime / 60 == 1)?"":"s",
- stoptime % 60, (stoptime % 60 == 1)?"":"s");
- else
- fprintf(outf, "Running time: %ld minute%s, %ld second%s.\n",
- stoptime / 60, (stoptime / 60 == 1)?"":"s",
- stoptime % 60, (stoptime % 60 == 1)?"":"s");
- }
-
- if (!aq && (mq || Wq || dq || Dq || hq || oq || Sq || iq || rq)) {
- gotos(outf, '\0');
- }
-
- /* Finally, insert footer file */
-
- footerfile[MAXSTRINGLENGTH - 5] = '\0'; /* for safety */
-
- if (!STREQ(footerfile, "none")) {
- if ((tempf = fopen(footerfile, "r")) == NULL) {
- if (warnq)
- fprintf(stderr,
- "%s: Warning: Failed to open footer file %s: ignoring it.\n",
- commandname, footerfile);
- }
- else { /* can open footer file */
- if (!aq)
- fprintf(outf, "<hr>");
- else {
- for (i = 0; i < pagewidth; i++)
- fprintf(outf, "-");
- }
- fprintf(outf, "\n\n");
- fflush(stdout);
-
- while(fgets(tempstr, MAXLINELENGTH, tempf) != NULL)
- fprintf(outf, "%s", tempstr);
- fclose(tempf);
- if (tempstr[(int)strlen(tempstr) - 1] != '\n')
- fprintf(outf, "\n");
-
- fprintf(outf, "\n");
- }
- }
-
- if (!aq) {
- if (STREQ(headerfile, "none") && STREQ(footerfile, "none")) {
- fprintf(outf,
- "<P> <A HREF=\"http://www.webtechs.com/html-val-svc/\">\n");
- fprintf(outf, "<IMG SRC=\"");
- htmlfprintf(outf, imagedir);
- fprintf(outf, "html2.gif\"\n");
- fprintf(outf, "ALT=\"HTML 2.0 Compliant!\"></A>\n");
- }
- fprintf(outf, "\n</body>\n</html>\n");
- }
- }
-
- fclose(outf);
-
- }
-